<template>
  <div class="app">
    <!-- Header -->
    <header class="app-header">
      <button class="back-btn" @click="goBack" aria-label="返回">
        <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M15 18l-6-6 6-6" />
        </svg>
      </button>
      <div class="brand">
        <div class="brand-icon" aria-hidden="true">
          <svg viewBox="0 0 24 24" class="icon" fill="none" stroke="currentColor" stroke-width="2"
            stroke-linecap="round" stroke-linejoin="round">
            <path d="M21 15a4 4 0 0 1-4 4H7l-4 4V5a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z" />
          </svg>
        </div>
        <div>
          <h1 class="title">群留言板</h1>
          <p class="subtitle">分享生活点滴 💬</p>
        </div>
      </div>
      <div class="meta">
        <div class="meta-count">{{ messages.length }}</div>
        <div class="meta-text">条留言</div>
      </div>
    </header>

    <main class="container">
      <!-- Composer -->
      <section class="card composer">
        <div class="card-head">
          <h2 class="card-title">写留言</h2>
          <p class="card-desc">用 @ 可以提醒群友哦</p>
        </div>

        <div class="composer-body">
          <textarea ref="textareaRef" v-model="message" @keydown="handleAtSymbol" :maxlength="200" class="textarea"
            placeholder="分享你的想法...\n输入 @ 可以提醒群友"></textarea>

          <!-- Mention list -->
          <div v-if="showMentionList" class="mention-list">
            <button v-for="member in otherMembers" :key="member" class="mention-item" type="button"
              @click="handleMentionSelect(member)">
              <svg class="mention-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                stroke-linecap="round" stroke-linejoin="round">
                <path d="M16 8a4 4 0 1 0-7.9 1H8a3 3 0 1 0 3 3h1V8" />
              </svg>
              <span>{{ member }}</span>
            </button>
          </div>

          <div class="composer-foot">
            <span class="counter">{{ message.length }}/200</span>
            <button class="btn btn-primary" :disabled="!message.trim()" @click="handleSendMessage">
              <svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                stroke-linecap="round" stroke-linejoin="round">
                <line x1="22" y1="2" x2="11" y2="13" />
                <polygon points="22 2 15 22 11 13 2 9 22 2" />
              </svg>
              发布
            </button>
          </div>
        </div>
      </section>

      <!-- Message list -->
      <section class="list">
        <article v-for="(msg, index) in messages" :key="msg.id" class="note"
          :class="[{ pinned: msg.isPinned }, index % 2 === 0 ? 'tilt-l' : 'tilt-r']" :style="noteStyle(msg.colorIndex)">
          <div v-if="msg.isPinned" class="pin-badge" title="已置顶">
            <svg viewBox="0 0 24 24" class="pin-badge-icon" fill="currentColor">
              <path d="M14 2l-2 2-4 1 5 5-5 10 10-5 5 5 1-4 2-2-12-12z" />
            </svg>
          </div>

          <header class="note-head">
            <div class="note-author">
              <span class="name">{{ msg.author }}</span>
              <span v-if="msg.author === currentUser" class="self">👤</span>
            </div>
            <div class="note-time">
              <svg class="clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
                stroke-linecap="round" stroke-linejoin="round">
                <circle cx="12" cy="12" r="10" />
                <polyline points="12 6 12 12 16 14" />
              </svg>
              <span>{{ formatTime(msg.timestamp) }}</span>
            </div>
          </header>

          <div class="note-content">
            <template v-for="(part, i) in partsWithMentions(msg.content)" :key="i">
              <span v-if="part.isMention" :class="['mention', part.isCurrent ? 'mention-me' : 'mention-other']">{{
                part.text }}</span>
              <span v-else>{{ part.text }}</span>
            </template>
          </div>

          <footer class="note-actions">
            <div class="actions-left">
              <button class="action like" :class="{ active: msg.likes.includes(currentUser) }"
                @click="handleLike(msg.id)">
                <svg viewBox="0 0 24 24" class="action-icon" :class="{ filled: msg.likes.includes(currentUser) }"
                  fill="currentColor">
                  <path
                    d="M12 21s-6.5-4.35-9-7.5C1 11 2.5 7 6 7c2 0 3.5 2 3.5 2S11 7 13 7c3.5 0 5 4 3 6.5-2.5 3.15-9 7.5-9 7.5z" />
                </svg>
                <span v-if="msg.likes.length">{{ msg.likes.length }}</span>
              </button>

              <button v-if="msg.author === currentUser" class="action pin" :class="{ active: msg.isPinned }"
                @click="handlePin(msg.id)">
                <svg viewBox="0 0 24 24" class="action-icon" :class="{ filled: msg.isPinned }" fill="currentColor">
                  <path d="M14 2l-2 2-4 1 5 5-5 10 10-5 5 5 1-4 2-2-12-12z" />
                </svg>
                <span>{{ msg.isPinned ? '已置顶' : '置顶' }}</span>
              </button>
            </div>

            <div v-if="msg.likes.length" class="actions-right">
              <span v-for="(user, idx) in msg.likes.slice(0, 3)" :key="idx" class="like-user">
                {{ user === currentUser ? '你' : user }}<span v-if="idx < msg.likes.length - 1">、</span>
              </span>
              <span class="like-tip">觉得很赞</span>
            </div>
          </footer>
        </article>
      </section>

      <!-- Tip -->
      <section class="tip">
        <div class="tip-icon" aria-hidden="true">
          <svg viewBox="0 0 24 24" class="icon" fill="none" stroke="currentColor" stroke-width="2"
            stroke-linecap="round" stroke-linejoin="round">
            <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
            <circle cx="9" cy="7" r="4" />
            <path d="M23 21v-2a4 4 0 0 0-3-3.87" />
            <path d="M16 3.13a4 4 0 0 1 0 7.75" />
          </svg>
        </div>
        <div>
          <p class="tip-title">温馨提示</p>
          <p class="tip-desc">用 @ 提醒好友，让重要消息不错过 ✨</p>
        </div>
      </section>
    </main>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'

type Message = {
  id: number
  author: string
  content: string
  timestamp: Date
  mentions: string[]
  likes: string[]
  isPinned: boolean
  colorIndex: number
}

// ⭐ 新增 router
const router = useRouter()
const goBack = () => {
  router.back()
}

const currentUser = '唐怡'
const message = ref('')
const showMentionList = ref(false)
const textareaRef = ref<HTMLTextAreaElement | null>(null)

const members = ['江秋月', '陈茜', '唐怡']
const otherMembers = computed(() => members.filter(m => m !== currentUser))

// 6 组淡雅便签色（不依赖 Tailwind）
const notePalettes = [
  ['#FEF3C7', '#FDE68A', '#F59E0B'], // amber
  ['#D1FAE5', '#A7F3D0', '#10B981'], // green
  ['#DBEAFE', '#BFDBFE', '#3B82F6'], // blue
  ['#FCE7F3', '#FBCFE8', '#EC4899'], // pink
  ['#EDE9FE', '#DDD6FE', '#8B5CF6'], // purple
  ['#FFEDD5', '#FED7AA', '#F97316']  // orange
]

const sample: Message[] = [
  { id: 1, author: '江秋月', content: '今天天气真好呀！适合出去走走 🌞', timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000), mentions: [], likes: ['陈茜'], isPinned: false, colorIndex: 0 },
  { id: 2, author: '陈茜', content: '@唐怡 你昨天推荐的那家餐厅真的很不错！下次我们一起去 😋', timestamp: new Date(Date.now() - 1 * 60 * 60 * 1000), mentions: ['唐怡'], likes: ['唐怡', '江秋月'], isPinned: false, colorIndex: 1 },
  { id: 3, author: '江秋月', content: '@陈茜 @唐怡 这周末有空吗？我们约个下午茶吧～有好多话想和你们聊 💕', timestamp: new Date(Date.now() - 30 * 60 * 1000), mentions: ['陈茜', '唐怡'], likes: ['陈茜'], isPinned: true, colorIndex: 2 },
]
const messages = ref<Message[]>([...sample].sort((a, b) => +b.timestamp - +a.timestamp))


function handleAtSymbol(e: KeyboardEvent) {
  if (e.key === '@') {
    showMentionList.value = true
  } else if (e.key === 'Escape') {
    showMentionList.value = false
  }
}

function handleMentionSelect(member: string) {
  const ta = textareaRef.value
  if (!ta) return
  const cursorPos = ta.selectionStart ?? message.value.length
  const textBefore = message.value.substring(0, Math.max(0, cursorPos - 1)) // 去掉@
  const textAfter = message.value.substring(cursorPos)
  message.value = `${textBefore}@${member} ${textAfter}`
  showMentionList.value = false
  requestAnimationFrame(() => {
    ta.focus()
    const newCursor = textBefore.length + member.length + 2
    ta.setSelectionRange(newCursor, newCursor)
  })
}

function handleSendMessage() {
  if (!message.value.trim()) return
  const mentionRegex = /@([^\s@]+)/g
  const mentions: string[] = []
  let match: RegExpExecArray | null
  while ((match = mentionRegex.exec(message.value)) !== null) {
    const who = match[1]
    if (members.includes(who) && !mentions.includes(who)) mentions.push(who)
  }
  const colorIndex = Math.floor(Math.random() * notePalettes.length)
  const newMsg: Message = {
    id: Date.now(),
    author: currentUser,
    content: message.value.trim(),
    timestamp: new Date(),
    mentions,
    likes: [],
    isPinned: false,
    colorIndex
  }
  messages.value = [newMsg, ...messages.value]
  message.value = ''
}

function handleLike(messageId: number) {
  messages.value = messages.value.map(m => m.id === messageId
    ? { ...m, likes: m.likes.includes(currentUser) ? m.likes.filter(u => u !== currentUser) : [...m.likes, currentUser] }
    : m
  )
}

function handlePin(messageId: number) {
  messages.value = messages.value
    .map(m => (m.id === messageId ? { ...m, isPinned: !m.isPinned } : m))
    .sort((a, b) => (a.isPinned && !b.isPinned ? -1 : !a.isPinned && b.isPinned ? 1 : +b.timestamp - +a.timestamp))
}

function formatTime(ts: Date) {
  const diff = Date.now() - +ts
  const m = Math.floor(diff / 60000)
  const h = Math.floor(diff / 3600000)
  const d = Math.floor(diff / 86400000)
  if (m < 1) return '刚刚'
  if (m < 60) return `${m}分钟前`
  if (h < 24) return `${h}小时前`
  if (d < 7) return `${d}天前`
  return new Date(ts).toLocaleDateString()
}

function partsWithMentions(content: string) {
  const raw = content.split(/(@[^\s@]+)/g)
  return raw.map(part => {
    if (part.startsWith('@')) {
      const who = part.slice(1)
      return { text: part, isMention: true, isCurrent: who === currentUser }
    }
    return { text: part, isMention: false, isCurrent: false }
  })
}

function noteStyle(idx: number) {
  const [from, to, border] = notePalettes[idx % notePalettes.length]
  return {
    background: `linear-gradient(135deg, ${from}, ${to})`,
    borderColor: border
  }
}
</script>

<style scoped>
:root {
  --max: 768px;
}

* {
  box-sizing: border-box;
}

body,
html,
.app {
  margin: 0;
  padding: 0;
}

.app {
  min-height: 100vh;
  background: linear-gradient(135deg, #FFF7ED, #FFEDD5);
}

.container {
  width: 100%;
  max-width: var(--max);
  padding: 16px;
}

/* Header */
.app-header {
  position: sticky;
  top: 0;
  z-index: 10;
  backdrop-filter: saturate(140%) blur(6px);
  background: rgba(255, 255, 255, 0.9);
  border-bottom: 1px solid #FDE68A;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, #34D399, #14B8A6);
  display: flex;
  align-items: center;
  justify-content: center;
}

.brand .icon {
  width: 22px;
  height: 22px;
  color: #fff;
}

.title {
  margin: 0;
  font-size: 18px;
  color: #1F2937;
  font-weight: 700;
}

.subtitle {
  margin: 2px 0 0;
  font-size: 12px;
  color: #6B7280;
}

.meta {
  text-align: right;
}

.meta-count {
  color: #059669;
  font-weight: 600;
}

.meta-text {
  font-size: 12px;
  color: #6B7280;
}

/* Card */
.card {
  background: #fff;
  border: 1px solid #FDE68A;
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  padding: 16px;
}

.card+.card {
  margin-top: 16px;
}

.card-title {
  margin: 0 0 4px;
  font-size: 15px;
  color: #1F2937;
  font-weight: 600;
}

.card-desc {
  margin: 0;
  font-size: 12px;
  color: #6B7280;
}

.composer .textarea {
  width: 100%;
  height: 96px;
  padding: 10px 12px;
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  resize: none;
  font-size: 14px;
  outline: none;
  transition: box-shadow .2s, border-color .2s;
}

.composer .textarea:focus {
  border-color: #A7F3D0;
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
}

.composer-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
}

.counter {
  font-size: 12px;
  color: #9CA3AF;
}

.btn {
  appearance: none;
  border: 0;
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.btn:disabled {
  opacity: .5;
  cursor: not-allowed;
}

.btn-primary {
  color: #fff;
  background: linear-gradient(90deg, #34D399, #0D9488);
  box-shadow: 0 4px 10px rgba(13, 148, 136, 0.25);
}

.btn-primary:hover {
  filter: brightness(1.05);
}

.btn-icon {
  width: 16px;
  height: 16px;
}

/* Mention list */
.mention-list {
  margin-top: 6px;
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 10px 18px rgba(0, 0, 0, .06);
  padding: 4px;
}

.mention-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: transparent;
  border: none;
  text-align: left;
  font-size: 14px;
  color: #111827;
  cursor: pointer;
}

.mention-item:hover {
  background: #ECFDF5;
}

.mention-icon {
  width: 12px;
  height: 12px;
  color: #059669;
}

/* Notes */
.list {
  display: grid;
  gap: 16px;
  margin-top: 16px;
}

.note {
  position: relative;
  padding: 16px;
  border: 2px solid #F59E0B;
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
  transform: rotate(0.5deg);
  transition: transform .2s;
}

.note.tilt-l {
  transform: rotate(1deg);
}

.note.tilt-r {
  transform: rotate(-1deg);
}

.note:hover {
  transform: rotate(0deg);
}

.pin-badge {
  position: absolute;
  right: -8px;
  top: -8px;
  width: 24px;
  height: 24px;
  border: 2px solid #fff;
  background: #FBBF24;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .12);
}

.pin-badge-icon {
  width: 14px;
  height: 14px;
  color: #78350F;
}

.note.pinned {
  outline: 2px solid #FDE68A;
  outline-offset: 2px;
}

.note-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.name {
  font-weight: 600;
  color: #111827;
}

.self {
  color: #059669;
  font-size: 12px;
  margin-left: 4px;
}

.note-time {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #4B5563;
  font-size: 12px;
}

.clock {
  width: 12px;
  height: 12px;
}

.note-content {
  color: #374151;
  font-size: 14px;
  line-height: 1.7;
  margin-bottom: 10px;
  word-break: break-word;
}

.mention {
  padding: 2px 4px;
  border-radius: 4px;
  font-weight: 600;
}

.mention-me {
  background: #A7F3D0;
  color: #065F46;
}

.mention-other {
  background: #FDE68A;
  color: #92400E;
}

.note-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.actions-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: transparent;
  color: #6B7280;
  font-size: 12px;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 8px;
}

.action:hover {
  background: #F3F4F6;
}

.action-icon {
  width: 12px;
  height: 12px;
  color: currentColor;
}

.action .filled {
  color: #EF4444;
}

.action.like.active {
  color: #EF4444;
}

.action.pin.active {
  color: #92400E;
}

.actions-right {
  display: flex;
  align-items: center;
  gap: 4px;
}

.like-user {
  color: #4B5563;
  font-size: 12px;
}

.like-tip {
  color: #6B7280;
  font-size: 12px;
}

/* Tip */
.tip {
  margin: 20px 0 28px;
  padding: 14px 16px;
  border: 1px solid #FCD34D;
  border-radius: 12px;
  background: linear-gradient(90deg, #FEF3C7, #FFEDD5);
  display: flex;
  align-items: center;
  gap: 12px;
}

.tip-icon .icon {
  width: 18px;
  height: 18px;
  color: #059669;
}

.tip-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #065F46;
}

.tip-desc {
  margin: 4px 0 0;
  font-size: 12px;
  color: #047857;
}

@media (max-width: 420px) {
  .title {
    font-size: 16px;
  }

  .composer .textarea {
    height: 88px;
  }
}

.back-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #374151;
  padding: 6px;
  border-radius: 6px;
  transition: background-color .2s;
}
.back-btn:hover {
  background-color: rgba(0,0,0,0.05);
}
</style>
